#pragma once

#include <mysql/mysql.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "../Headers/types.h"
#include "../Headers/authr.h"
#include "../Headers/log.h"
#include "../Headers/config.h"

#ifndef CONFIG
#define CONFIG ("us-server.cfg")
#endif

namespace TOB{

  class US {

  private:

    int connectDB();
    int disconnectDB();
    int checkField(std::string field);
    int checkFieldValue (std::string field, std::string value);

    Config *config;
  public:
    MYSQL mysql;
    MYSQL_RES *mysql_res;
    MYSQL_ROW mysql_row;
    MYSQL_FIELD mysql_field;

   US();
   ~US();


/**
  *  Возвращает числом значение поля policy или role
  *
  *  @param login = логин для поиска записи
  *  @param value = возвращаемое числовое значение
  *  @result = успешная или неуспешная операция
*/
Code::Type getUintByLogin(std::string login, std::string field, int& value);

  /**
   *  getStringByLogin:
   *  Функция возвращает строковое значение в value указанного поля field в соответствии с указанным логином login. 
   *
   *  @param login std::string = логин пользователя;
   *  @param field std::string = название поля, значение которого возвращается("password"||"role"||"policy"||"name")
   *  @param value std::string& = переменная, в которую передается найденное значение поля
   *
   *  @return возвращает код ошибки, если ошибка и "0" и значение в value, если успех(запрос выполнен)  
  */
Code::Type getStringByLogin (std::string login, std::string field, std::string& value);

  /**
   *  existenceLogin:
   *  Функция ищет запись с логином login и возвращает в value: 0 - в случае удачи, 1 - если запись не найдена
   *
   *  @param login std::string = логин пользователя;
   *  @param value std::int& = переменная, которая передает результат выполнения операции (0=логин найден;1=логин не найден)
   *
   *  @return возвращает код ошибки, если ошибка и "0" и значение в value, если успех(запрос выполнен)  
  */
Code::Type existenceLogin (std::string login, int& value);

  /**
   *  updateFieldByLogin:
   *  Функция записывает в поле field значение value в строке с логином login.
   *
   *  @param login std::string = логин пользователя;
   *  @param field std::string = название поля, значение которого изменяется("password"||"role"||"policy"||"name")
   *  @param value std::string = новое значение
   *
   *  @return возвращает код ошибки, если ошибка и "0", если успех(запрос выполнен)  
  */
Code::Type updateFieldByLogin (std::string login, std::string field, std::string value);

  /**
   *  appendRow:
   *  Функция создает новую запись с уникальным логином login и значениями остальных полей.
   *  Поле name не является обязательным и имеет значение по умолчанию = ""
   *
   *  @param login std::string = логин пользователя, если такой уже существует в таблице, то будет возвращена ошибка;
   *  @param password std::string = пароль пользователя
   *  @param role std::string = роль пользователя=одно значение из множества DBrole_list: ("User","Administrator")
   *  @param policy std::string = названия разрешенных модулей=одно или несколько значений из множества DBpolicy_list:
   *  ("AllowUserManagement","AllowMail", "AllowToDo", "AllowFileSharing","AllowCalendar","AllowDirectory","AllowTime","DenyAll")
   *  !!! Если значений поля policy несколько, то они должны быть разделены "," (запятой) без пробелов и каждое в кавычках!
   *  @param name std::string = имя пользователя, необязательное поле, значение по умолчанию: ""
   *
   *  @return возвращает код ошибки, если ошибка и "0", если успех(запрос выполнен)  
  */
Code::Type appendRow (std::string login, std::string password, std::string role, std::string policy, std::string name="");

  /**
   *  deleteRow:
   *  Функция ищет запись с логином login и удаляет её.
   *
   *  @param login std::string = логин пользователя;
   *
   *  @return возвращает код ошибки, если ошибка и "0" и значение в value, если успех(запрос выполнен)  
  */
Code::Type deleteRowByLogin (std::string login);

};
};

